package me.shihao.serialportdemo.serialport

import java.util.*
import kotlin.math.pow

/**
 * author: shihao
 * date: 2021/3/5 16:42
 * description:
 */
object KTDataUtils {

    private val binaryArray = arrayListOf(
        "0000", "0001", "0010", "0011",
        "0100", "0101", "0110", "0111",
        "1000", "1001", "1010", "1011",
        "1100", "1101", "1110", "1111"
    )

    /**
     * 字节数组转二进制代码字符串
     */
    fun byteArrayToBinStr(byteArray: ByteArray): String {
        var outStr = ""
        var pos: Int
        for (b in byteArray) {
            //高四位
            pos = (b.toInt() and 0xF0) shr 4
            outStr += binaryArray[pos]
            //低四位
            pos = b.toInt() and 0x0F
            outStr += binaryArray[pos]
        }
        return outStr
    }


    /**
     * 判断奇数或偶数，位运算，最后一位是1则为奇数，为0是偶数
     */
    fun isOdd(num: Int): Int {
        return num and 1
    }

    /**
     * 16进制字符串转10进制
     */
    fun hexToInt(inHex: String): Int {
        return inHex.toInt(16)
    }

    /**
     * 无符号十六进制转有符号十进制
     */
    fun hexToSignedInt(inHex: String): Int {
        val bin = byteArrayToBinStr(hexToByteArray(inHex))
        var result = 0
        if (bin.startsWith("0")) {
            //正数
            result = hexToInt(inHex)
        } else {
            //负数
            //减1
            var temp: String = bin
            for ((i, c) in bin.reversed().withIndex()) {
                if (c == '1') {
                    temp = temp.replaceRange(bin.length - 1 - i, bin.length - i, "0")
                    break
                } else {
                    temp = temp.replaceRange(bin.length - 1 - i, bin.length - i, "1")
                }
            }
            //取反,转十进制
            temp.reversed().forEachIndexed { index, c ->
                val i = ((if (c == '1') 0 else 1) * 2.0.pow(index.toDouble())).toInt()
                result -= i
            }
        }
        return result
    }

    /**
     * 10进制转16进制,不足偶数位的前面补0
     */
    fun intToHex(intHex: Int): String {
        var hex = intHex.toString(16)
        if (hex.length % 2 != 0)
            hex = "0$hex"
        return hex.toUpperCase()
    }

    /**
     * 10进制转16进制,字节位数不足的前面补0
     * @param intHex 10进制数字
     * @param byteNum 格式化多少十六进制个字节，不足的会在前面补0
     */
    fun intToHex(intHex: Int, byteNum: Int): String {
        var hex = intHex.toString(16)
        while (hex.length < byteNum * 2) {
            hex = "0$hex"
        }
        return hex.toUpperCase()
    }

    /**
     * 十六进制转字节
     */
    fun hexToByte(inHex: String): Byte {
        return inHex.toInt(16).toByte()
    }

    /**
     * 字节转16进制字符串
     */
    fun byteToHex(byte: Byte): String {
        return String.format("%02x", byte).toUpperCase(Locale.getDefault())
    }

    /**
     * 字节数组转16进制字符串
     */
    fun byteArrayToHex(array: ByteArray): String {
        val builder = StringBuilder()
        for (byte in array) {
            builder.append(byteToHex(byte)).append(" ")
        }
        return builder.toString().trim()
    }

    /**
     * 字节数组转16进制字符串,中间无分割
     */
    fun byteArrayToHexTrim(array: ByteArray): String {
        val builder = StringBuilder()
        for (byte in array) {
            builder.append(byteToHex(byte))
        }
        return builder.toString().trim()
    }

    /**
     * 16进制字符串转字节数组
     */
    fun hexToByteArray(hex: String): ByteArray {
        var hexLen: Int = hex.length
        var hexStr = hex
        if (isOdd(hexLen) == 1) {
            hexLen++
            hexStr = "0$hex"
        }
        val byteArray = ByteArray(hexLen / 2)
        for ((j, i) in (0 until hexLen step 2).withIndex()) {
            byteArray[j] = hexToByte(hexStr.substring(i, i + 2))
        }
        return byteArray
    }
}